﻿using Castle.Core.Internal;
using Common.AspNetCore;
using Common.Infrastructure;
using Common.Infrastructure.Structs;
using Common.RunModels.Base;
using DotNetCore.CAP;
using Report.Api.Models;
using Report.Api.Models.Tier;
using StatsData.Api.Models;
using StatsData.Api.Repository;
using StatsData.Data.Entity;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Security.Cryptography;
using System.Threading.Tasks;

namespace StatsData.Api.Service
{
    public class SyncService : CommonService
    {
        private readonly StatsDataRepository statsDataRepository;

        public SyncService(IServiceProvider provider, StatsDataRepository stats) : base(provider)
        {
            this.statsDataRepository = stats;
        }

        public async Task<SystemTranslateResultModel> RetryTranslateAsync(List<string> translates, string langs = "EN")
        {
            var langList = new List<string>();
            if (!string.IsNullOrEmpty(langs))
            {
                var tmpLangs = langs.Split(',', StringSplitOptions.RemoveEmptyEntries);
                langList.AddRange(tmpLangs);
            }

            for (var i = 0; i < 3; i++)
            {
                try
                {
                    return await this.CallService.PostGetAsync<SystemTranslateResultModel>("Base", "Base/SystemTranslate", new SystemTranslateParamModel() { SrcValues = translates, Langs = langList });
                }
                catch
                {
                }
            }

            return null;
        }

        /// <summary>
        /// 同步组织
        /// </summary>
        /// <returns></returns>
        public async Task<bool> SyncOrgAsync()
        {
            var orgs = await this.CallService.PostGetAsync<List<OrgCache>>("Base", "BaseData/GetOrgs");
            var orgIds = orgs.Select(t => t.Id).ToList();
            var orgList = await this.statsDataRepository.CommonRepository.GetEntitiesAsync<t_organization>(orgIds);
            var orgNames = orgs.Where(t => !string.IsNullOrEmpty(t.Name)).Select(t => t.Name).Distinct().ToList();
            var ens = await this.RetryTranslateAsync(orgNames);
            orgs.ForEach(t =>
            {
                var orgInfo = orgList.FirstOrDefault(s => s.id == t.Id);
                var enName = ens?.Details.FirstOrDefault(x => x.SrcValue == t.Name);
                if (orgInfo == null)
                {
                    orgInfo = new t_organization()
                    {
                        id = t.Id,
                        name = t.Name,
                        code = t.Code,
                        name_en = enName?.TranValue
                    };

                    orgList.Add(orgInfo);
                } 
                else
                {
                    orgInfo.name_en = enName?.TranValue;
                }
            });

            await this.statsDataRepository.CommitChangesByCommonAsync(() =>
            {
                this.statsDataRepository.CommonRepository.SaveEntities(orgList);
            });

            return true;
        }

        /// <summary>
        /// 同步部门
        /// </summary>
        /// <returns></returns>
        public async Task<bool> SyncDepartmentAsync(ApiParam apiParam)
        {
            var departments = await this.CallService.PostGetAsync<List<DepartModel>>("Base", "BaseData/GetLineDepartmentModels", apiParam);
            var departmentIds = departments.Select(t => t.id).ToList();
            var departmentList = await this.statsDataRepository.CommonRepository.GetEntitiesAsync<t_department>(departmentIds);
            List<t_department> addList = new List<t_department>();
            List<t_department> updateList = new List<t_department>();
            var departNames = departments.Where(t => !string.IsNullOrEmpty(t.DepartName)).Select(t => t.DepartName).ToList();
            var ens = await this.RetryTranslateAsync(departNames);
            departments.ForEach(t =>
            {
                var departmentInfo = departmentList.FirstOrDefault(s => s.id == t.id);
                var enName = ens?.Details.FirstOrDefault(x => x.SrcValue == t.DepartName);
                if (departmentInfo == null)
                {
                    departmentInfo = new t_department()
                    {
                        id = t.id,
                        name = t.DepartName,
                        name_en = enName?.TranValue,
                        code = t.DepartCode,
                        parent_id = t.ParentId,
                        is_line = t.IsLine,
                        level = t.Level,
                        org_id = apiParam.OrgId
                    };

                    addList.Add(departmentInfo);
                }
                else
                {
                    bool isUpdate = false;

                    if (departmentInfo.is_line != t.IsLine)
                    {
                        departmentInfo.is_line = t.IsLine;
                        isUpdate = true;
                    }

                    if (departmentInfo.level != t.Level)
                    {
                        departmentInfo.level = t.Level;
                        isUpdate = true;
                    }

                    if (departmentInfo.name != t.DepartName)
                    {
                        departmentInfo.name = t.DepartName;
                        isUpdate = true;
                    }

                    if (departmentInfo.parent_id != t.ParentId)
                    {
                        departmentInfo.parent_id = t.ParentId;
                        isUpdate = true;
                    }

                    if (string.IsNullOrEmpty(departmentInfo.name_en))
                    {
                        departmentInfo.name_en = enName?.TranValue;
                        isUpdate = true;
                    }
                    
                    if (isUpdate)
                    {
                        updateList.Add(departmentInfo);
                    }
                }
            });

            await this.statsDataRepository.CommitChangesByCommonAsync(() =>
            {
                this.statsDataRepository.CommonRepository.AddEntities(addList);
                this.statsDataRepository.CommonRepository.UpdateEntities(updateList);
            });

            return true;
        }

        /// <summary>
        /// 同步员工
        /// </summary>
        /// <returns></returns>
        public async Task<bool> SyncUserAsync(ApiParam apiParam)
        {
            var users = await this.CallService.PostGetAsync<List<UserModel>>("Base", "BaseData/GetUserFullByOrg", apiParam);
            var userList = await this.statsDataRepository.CommonRepository.GetEntitiesAsync<t_user>(t => t.org_id == apiParam.OrgId);
            List<t_user> addList = new List<t_user>();
            List<t_user> updateList = new List<t_user>();

            var names = users.Where(t => !string.IsNullOrEmpty(t.Name)).Select(t => t.Name).Distinct().ToList();
            var translates = await this.RetryTranslateAsync(names);
            users.ForEach(t =>
            {
                var userInfo = userList.FirstOrDefault(s => s.id == t.Id);
                var trans = translates?.Details?.FirstOrDefault(x => x.SrcValue == t.Name);
                if (userInfo == null)
                {
                    userInfo = new t_user()
                    {
                        id = t.Id,
                        name = t.Name,
                        code = t.Code,
                        depart_id = t.DepartId,
                        lcp_code = t.LcpCode,
                        org_id = apiParam.OrgId,
                        name_en = trans?.TranValue
                    };

                    addList.Add(userInfo);
                }
                else
                {
                    bool isUpdate = false;

                    if (userInfo.name != t.DepartId)
                    {
                        userInfo.name = t.DepartId;
                        isUpdate = true;
                    }

                    if (userInfo.lcp_code != t.LcpCode)
                    {
                        userInfo.lcp_code = t.LcpCode;
                        isUpdate = true;
                    }

                    if (string.IsNullOrEmpty(userInfo.name_en))
                    {
                        userInfo.name_en = trans?.TranValue;
                        isUpdate = true;
                    }

                    if (isUpdate)
                    {
                        updateList.Add(userInfo);
                    }
                }
            });

            await this.statsDataRepository.CommitChangesByCommonAsync(() =>
            {
                this.statsDataRepository.CommonRepository.AddEntities(addList);
                this.statsDataRepository.CommonRepository.UpdateEntities(updateList);
            });

            return true;
        }

        /// <summary>
        /// 同步产线
        /// </summary>
        /// <returns></returns>
        public async Task<bool> SyncLineAsync(List<Line> model)
        {
            var orgId = model.FirstOrDefault()?.OrgId;
            var lineList = await this.statsDataRepository.CommonRepository.GetEntitiesAsync<t_line>(t => t.org_id == orgId);
            List<t_line> addList = new List<t_line>();
            List<t_line> updateList = new List<t_line>();
            var lineNames = model.Where(t => !string.IsNullOrEmpty(t.Name)).Select(t => t.Name).Distinct().ToList();
            var workshopNames = model.Where(t => !string.IsNullOrEmpty(t.WorkShopName)).Select(t => t.WorkShopName).Distinct().ToList();
            var sts = new List<string>();
            if (lineNames != null && lineNames.Any())
            {
                sts.AddRange(lineNames);
            }

            if (workshopNames != null && workshopNames.Any())
            {
                sts.AddRange(workshopNames);
            }

            var ens = await this.RetryTranslateAsync(sts);
            model.ForEach(t =>
            {
                var lineInfo = lineList.FirstOrDefault(s => s.id == t.Id);
                var enName = ens?.Details.FirstOrDefault(x => x.SrcValue == t.Name);
                var workshopEnName = ens?.Details.FirstOrDefault(x => x.SrcValue == t.WorkShopName);
                if (lineInfo == null)
                {
                    lineInfo = new t_line()
                    {
                        id = t.Id,
                        line_code = t.Code,
                        line_name = t.Name,
                        line_name_en = enName?.TranValue,
                        workshop_code = t.WorkShopCode,
                        workshop_name = t.WorkShopName,
                        workshop_name_en = workshopEnName?.TranValue,
                        org_id = t.OrgId
                    };

                    addList.Add(lineInfo);
                }
                else
                {
                    bool isUpdate = false;

                    if (lineInfo.workshop_code != t.WorkShopCode)
                    {
                        lineInfo.workshop_code = t.WorkShopCode;
                        isUpdate = true;
                    }

                    if (lineInfo.workshop_name != t.WorkShopName)
                    {
                        lineInfo.workshop_name = t.WorkShopName;
                        isUpdate = true;
                    }

                    if (lineInfo.line_name != t.Name)
                    {
                        lineInfo.line_name = t.Name;
                        isUpdate = true;
                    }

                    if (lineInfo.workshop_name_en != workshopEnName?.TranValue)
                    {
                        lineInfo.workshop_name_en = workshopEnName?.TranValue;
                        isUpdate = true;
                    }

                    if (lineInfo.line_name_en != enName?.TranValue)
                    {
                        lineInfo.line_name_en = enName?.TranValue;
                        isUpdate = true;
                    }

                    if (isUpdate)
                    {
                        updateList.Add(lineInfo);
                    }
                }
            });

            await this.statsDataRepository.CommitChangesByCommonAsync(() =>
            {
                this.statsDataRepository.CommonRepository.AddEntities(addList);
                this.statsDataRepository.CommonRepository.UpdateEntities(updateList);
            });

            return true;
        }

        /// <summary>
        /// 同步不良
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        public async Task<bool> SyncBadAsync(List<BadRecordModel> model)
        {
            var beginDate = model.Min(t => t.Date);
            var endDate = model.Max(t => t.Date);
            var orgId = model.FirstOrDefault()?.OrgId;
            var badList = await this.statsDataRepository.CommonRepository.GetEntitiesAsync<t_bad>(t => t.curr_date >= beginDate && t.curr_date <= endDate && t.org_id == orgId);
            List<t_bad> addList = new List<t_bad>();
            List<t_bad> updateList = new List<t_bad>();
            var translateStrs = model.Where(t => !string.IsNullOrEmpty(t.BadCodeName)).Select(t => t.BadCodeName).Distinct().ToList();
            if (translateStrs == null)
            {
                translateStrs = new List<string>();
            }

            var procedure = model.Where(t => !string.IsNullOrEmpty(t.ProcedureName)).Select(t => t.ProcedureName).Distinct().ToList();

            if (procedure != null)
            {
                translateStrs.AddRange(procedure);
            }

            var lineName = model.Where(t => !string.IsNullOrEmpty(t.LineName)).Select(t => t.LineName).Distinct().ToList();

            if (lineName != null)
            {
                translateStrs.AddRange(lineName);
            }

            var translates = await this.RetryTranslateAsync(translateStrs);
            model.ForEach(t =>
            {
                var badInfo = badList.FirstOrDefault(s => s.curr_date == t.Date && s.line_code == t.LineCode && s.procedure_code == t.ProcedureCode && t.BadCode == s.bad_code && t.Type == s.type);
                var badTranslate = translates?.Details?.FirstOrDefault(x => x.SrcValue == t.BadCodeName);
                var procedureTranslate = translates?.Details?.FirstOrDefault(x => x.SrcValue == t.ProcedureName);
                var lineTranslate = translates?.Details?.FirstOrDefault(x => x.SrcValue == t.LineName);
                if (badInfo == null)
                {
                    badInfo = new t_bad()
                    {
                        line_code = t.LineCode,
                        line_name = t.LineName,
                        line_name_en = lineTranslate?.TranValue,
                        produre_name_en = procedureTranslate?.TranValue,
                        procedure_name = t.ProcedureName,
                        procedure_code = t.ProcedureCode,
                        bad_code = t.BadCode,
                        org_id = t.OrgId,
                        bad_name = t.BadCodeName,
                        qty = t.BadQty,
                        type = t.Type,
                        curr_date = t.Date,
                        bad_name_en = badTranslate?.TranValue,
                    };

                    this.SetEntityId(badInfo);

                    addList.Add(badInfo);
                }
                else
                {
                    bool isUpdate = false;
                    if (badInfo.qty != t.BadQty)
                    {
                        badInfo.qty = t.BadQty;
                        isUpdate = true;
                    }

                    if (badInfo.procedure_name != t.ProcedureName)
                    {
                        badInfo.procedure_name = t.ProcedureName;
                        isUpdate = true;
                    }

                    if (badInfo.bad_name != t.BadCodeName)
                    {
                        badInfo.bad_name = t.BadCodeName;
                        isUpdate = true;
                    }

                    if (string.IsNullOrEmpty(badInfo.produre_name_en))
                    {
                        badInfo.produre_name_en = procedureTranslate?.TranValue;
                        isUpdate = true;
                    }

                    if (string.IsNullOrEmpty(badInfo.line_name_en))
                    {
                        badInfo.line_name_en = lineTranslate?.SrcValue;
                        isUpdate = true;
                    }

                    if (string.IsNullOrEmpty(badInfo.bad_name_en))
                    {
                        badInfo.bad_name_en = badTranslate?.TranValue;
                        isUpdate = true;
                    }

                    if (string.IsNullOrEmpty(badInfo.line_name))
                    {
                        badInfo.line_name = t.LineName;
                        isUpdate = true;
                    }

                    if (isUpdate)
                    {
                        updateList.Add(badInfo);
                    }
                }
            });

            await this.statsDataRepository.CommitChangesByCommonAsync(() =>
            {
                this.statsDataRepository.CommonRepository.AddEntities(addList);
                this.statsDataRepository.CommonRepository.UpdateEntities(updateList);
            });

            return true;
        }

        /// <summary>
        /// 同步OQC
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        public async Task<bool> SyncOQCAsync(List<OQCStatisModel> model)
        {
            var beginDate = model.Min(t => t.Date);
            var endDate = model.Max(t => t.Date);
            var orgId = model.FirstOrDefault()?.OrgId;
            var oqcList = await this.statsDataRepository.CommonRepository.GetEntitiesAsync<t_qc>(t => t.curr_date >= beginDate && t.curr_date <= endDate && t.org_id == orgId);
            List<t_qc> addList = new List<t_qc>();
            List<t_qc> updateList = new List<t_qc>();
            var translates = await this.RetryTranslateAsync(model.Where(t => !string.IsNullOrEmpty(t.LineName)).Select(t => t.LineName).Distinct().ToList());
            model.ForEach(t =>
            {
                var qcInfo = oqcList.FirstOrDefault(s => s.curr_date == t.Date && s.line_code == t.LineCode);
                var trans = translates?.Details.FirstOrDefault(x => x.SrcValue == t.LineName);
                if (qcInfo == null)
                {
                    qcInfo = new t_qc()
                    {
                        line_code = t.LineCode,
                        checked_ok_qty = t.CheckedOkQty,
                        checked_qty = t.CheckedQty,
                        checked_batch_qty = t.CheckedBatchQty,
                        org_id = t.OrgId,
                        checked_batch_ok_qty = t.CheckedBatchOKQty,
                        qty = t.Qty,
                        curr_date = t.Date,
                        line_name = t.LineName,
                        line_name_en = trans.TranValue
                    };

                    this.SetEntityId(qcInfo);

                    addList.Add(qcInfo);
                }
                else
                {
                    bool isUpdate = false;
                    if (qcInfo.qty != t.Qty)
                    {
                        qcInfo.qty = t.Qty;
                        isUpdate = true;
                    }

                    if (qcInfo.checked_ok_qty != t.CheckedOkQty)
                    {
                        qcInfo.checked_ok_qty = t.CheckedOkQty;
                        isUpdate = true;
                    }

                    if (qcInfo.checked_qty != t.CheckedQty)
                    {
                        qcInfo.checked_qty = t.CheckedQty;
                        isUpdate = true;
                    }

                    if (qcInfo.checked_batch_qty != t.CheckedBatchQty)
                    {
                        qcInfo.checked_batch_qty = t.CheckedBatchQty;
                        isUpdate = true;
                    }

                    if (qcInfo.checked_batch_ok_qty != t.CheckedBatchOKQty)
                    {
                        qcInfo.checked_batch_ok_qty = t.CheckedBatchOKQty;
                        isUpdate = true;
                    }

                    if (string.IsNullOrEmpty(qcInfo.line_name_en))
                    {
                        qcInfo.line_name_en = trans?.TranValue;
                        isUpdate = true;
                    }

                    if (string.IsNullOrEmpty(qcInfo.line_name))
                    {
                        qcInfo.line_name = t.LineName;
                        isUpdate = true;
                    }

                    if (isUpdate)
                    {
                        updateList.Add(qcInfo);
                    }
                }
            });

            await this.statsDataRepository.CommitChangesByCommonAsync(() =>
            {
                this.statsDataRepository.CommonRepository.AddEntities(addList);
                this.statsDataRepository.CommonRepository.UpdateEntities(updateList);
            });

            return true;
        }

        /// <summary>
        /// 同步异常
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        public async Task<bool> SyncExceptionAsync(List<QCExceptionModel> model)
        {
            var beginDate = model.Min(t => t.Date);
            var endDate = model.Max(t => t.Date);
            var orgId = model.FirstOrDefault()?.OrgId;
            var execeptionList = await this.statsDataRepository.CommonRepository.GetEntitiesAsync<t_qc_exception>(t => t.curr_date >= beginDate && t.curr_date <= endDate && t.org_id == orgId);
            List<t_qc_exception> addList = new List<t_qc_exception>();
            List<t_qc_exception> updateList = new List<t_qc_exception>();
            var translates = await this.RetryTranslateAsync(model.Where(t => !string.IsNullOrEmpty(t.LineName)).Select(t => t.LineName).Distinct().ToList());
            model.ForEach(t =>
            {
                var execptionInfo = execeptionList.FirstOrDefault(s => s.curr_date == t.Date && s.line_code == t.LineCode);
                var trans = translates?.Details?.FirstOrDefault(x => x.SrcValue == t.LineName);
                if (execptionInfo == null)
                {
                    execptionInfo = new t_qc_exception()
                    {
                        line_code = t.LineCode,
                        org_id = t.OrgId,
                        ng_qty = t.NGQty,
                        qty = t.Qty,
                        curr_date = t.Date,
                        line_name = t.LineName,
                        line_name_en = trans?.TranValue
                    };

                    this.SetEntityId(execptionInfo);

                    addList.Add(execptionInfo);
                }
                else
                {
                    bool isUpdate = false;
                    if (execptionInfo.qty != t.Qty)
                    {
                        execptionInfo.qty = t.Qty;
                        isUpdate = true;
                    }

                    if (execptionInfo.ng_qty != t.NGQty)
                    {
                        execptionInfo.ng_qty = t.NGQty;
                        isUpdate = true;
                    }

                    if (string.IsNullOrEmpty(execptionInfo.line_name))
                    {
                        execptionInfo.line_name = t.LineName;
                        isUpdate = true;
                    }

                    if (string.IsNullOrEmpty(execptionInfo.line_name_en))
                    {
                        execptionInfo.line_name_en = trans?.TranValue;
                        isUpdate = true;
                    }

                    if (isUpdate)
                    {
                        updateList.Add(execptionInfo);
                    }
                }
            });

            await this.statsDataRepository.CommitChangesByCommonAsync(() =>
            {
                this.statsDataRepository.CommonRepository.AddEntities(addList);
                this.statsDataRepository.CommonRepository.UpdateEntities(updateList);
            });

            return true;
        }

        /// <summary>
        /// 同步CSI
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        public async Task<bool> SyncCSIAsync(CSIModel model)
        {
            var beginDate = model.Details.Min(t => t.Date);
            var endDate = model.Details.Max(t => t.Date);
            var csiList = await this.statsDataRepository.CommonRepository.GetEntitiesAsync<t_csi>(t => t.curr_date >= beginDate && t.curr_date <= endDate && t.org_id == model.OrgId);
            List<t_csi> addList = new List<t_csi>();
            List<t_csi> updateList = new List<t_csi>();

            model.Details.ForEach(t =>
            {
                var csiInfo = csiList.FirstOrDefault(s => s.curr_date == t.Date && s.batch == t.Batch);

                if (csiInfo == null)
                {
                    csiInfo = new t_csi()
                    {
                        batch = t.Batch,
                        org_id = model.OrgId,
                        type = t.Type,
                        begin_time = t.BeginTime,
                        end_time = t.EndTime,
                        curr_date = t.Date,
                        item_no = t.ItemNo,
                        so_no = t.SONo,
                        so_item = t.SOItem,
                        pdt_no = t.PdtNO,
                        cust_no = t.CustNo,
                        result_no = t.ResultNo,
                        result = t.Result,
                        line_code = t.LineCode
                    };

                    if (csiInfo.pdt_no != null && csiInfo.pdt_no.Length > 600)
                    {
                        csiInfo.pdt_no = csiInfo.pdt_no.Substring(0, 600);
                    }

                    this.SetEntityId(csiInfo);

                    addList.Add(csiInfo);
                }
                else
                {
                    bool isUpdate = false;
                    if (csiInfo.result_no != t.ResultNo)
                    {
                        csiInfo.result_no = t.ResultNo;
                        isUpdate = true;
                    }

                    if (csiInfo.result != t.Result)
                    {
                        csiInfo.result = t.Result;
                        isUpdate = true;
                    }

                    if (isUpdate)
                    {
                        updateList.Add(csiInfo);
                    }
                }
            });

            await this.statsDataRepository.CommitChangesByCommonAsync(() =>
            {
                this.statsDataRepository.CommonRepository.AddEntities(addList);
                this.statsDataRepository.CommonRepository.UpdateEntities(updateList);
            });

            return true;
        }

        /// <summary>
        /// 同步生产数据
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        public async Task<bool> SyncProduceAsync(List<ProduceSyncModel> model)
        {
            if (!model.Any())
            {
                return true;
            }

            var beginDate = model.Min(t => t.Time);
            var endDate = model.Max(t => t.Time);
            var orgId = model.FirstOrDefault()?.OrgId;
            var produceList = await this.statsDataRepository.CommonRepository.GetEntitiesAsync<t_produce_statis>(t => t.curr_date >= beginDate && t.curr_date <= endDate && t.org_id == orgId);
            List<t_produce_statis> addList = new List<t_produce_statis>();
            List<t_produce_statis> updateList = new List<t_produce_statis>();
            var translate = await this.RetryTranslateAsync(model.Where(t => !string.IsNullOrEmpty(t.LineName)).Select(t => t.LineName).Distinct().ToList());
            model.ForEach(t =>
            {
                var produceInfo = produceList.FirstOrDefault(s => s.curr_date.Date == t.Time.Date && s.line_code == t.LineCode);
                var trans = translate?.Details.FirstOrDefault(x => x.SrcValue == t.LineName);
                if (produceInfo == null)
                {
                    produceInfo = new t_produce_statis()
                    {
                        line_code = t.LineCode,
                        line_name = t.LineName,
                        line_name_en = trans?.TranValue,
                        org_id = t.OrgId,
                        curr_date = t.Time,
                        total_in_qty = t.TotalInQty,
                        plan_total_finish_pcs_qty = t.TargetPCSQty,
                        total_finish_qty = t.TotalFinishQty,
                        last_procedure_finish_qty = t.LastProcedureFinishQty,
                        plan_total_finish_qty = t.PlanTotalFinishQty,
                        plan_total_warehouse_qty = t.PlanTotalWarehouseQty,
                        total_warehouse_qty = t.TotalWarehouseQty,
                        total_bad_qty = t.TotalBadQty,
                        total_in_user_work_hour = t.TotalInUserWorkHour,
                        total_finish_user_work_hour = t.TotalFinishUserWorkHour,
                        total_total_work_hour = t.TotalTotalWorkHour,
                        total_user_work_hour = t.TotalUserWorkHour,
                        total_user_qty = t.TotalUserQty,
                        /// 应出勤人数
                        today_plan_user_qty = t.TotalPlanUserQty,
                        today_work_hour = t.PlanTotalWorkHour,
                        line_work_hour = t.LineWorkHour,
                        oqc_send_qty = t.OqcQty,
                        delay_plan_qty = t.PlanDelayQty,
                        present_user_qty = t.PresentUserQty,
                        plan_total_total_work_hour = t.PlanTotalTotalWorkHour,
                        other_standard_time = t.OtherStandardTime,
                        other_total_work_hour = t.OtherTotalWorkHour,
                        total_finish_user_attend_hour = t.TotalFinishUserAttendHour,
                        total_in_user_attend_hour = t.TotalInUserAttendHour
                    };

                    this.SetEntityId(produceInfo);
                    addList.Add(produceInfo);
                }
                else
                {
                    bool isUpdate = false;
                    if (produceInfo.total_in_qty != t.TotalInQty)
                    {
                        produceInfo.total_in_qty = t.TotalInQty;
                        isUpdate = true;
                    }

                    if (produceInfo.present_user_qty != t.PresentUserQty)
                    {
                        produceInfo.present_user_qty = t.PresentUserQty;
                        isUpdate = true;
                    }

                    if (produceInfo.total_finish_qty != t.TotalFinishQty)
                    {
                        produceInfo.total_finish_qty = t.TotalFinishQty;
                        isUpdate = true;
                    }

                    if (produceInfo.total_total_work_hour != t.TotalTotalWorkHour)
                    {
                        produceInfo.total_total_work_hour = t.TotalTotalWorkHour;
                        isUpdate = true;
                    }

                    if (produceInfo.total_user_work_hour != t.TotalUserWorkHour)
                    {
                        produceInfo.total_user_work_hour = t.TotalUserWorkHour;
                        isUpdate = true;
                    }

                    if (produceInfo.last_procedure_finish_qty != t.LastProcedureFinishQty)
                    {
                        produceInfo.last_procedure_finish_qty = t.LastProcedureFinishQty;
                        isUpdate = true;
                    }

                    if (produceInfo.plan_total_finish_qty != t.PlanTotalFinishQty)
                    {
                        produceInfo.plan_total_finish_qty = t.PlanTotalFinishQty;
                        isUpdate = true;
                    }

                    if (produceInfo.plan_total_warehouse_qty != t.PlanTotalWarehouseQty)
                    {
                        produceInfo.plan_total_warehouse_qty = t.PlanTotalWarehouseQty;
                        isUpdate = true;
                    }

                    if (produceInfo.total_warehouse_qty != t.TotalWarehouseQty)
                    {
                        produceInfo.total_warehouse_qty = t.TotalWarehouseQty;
                        isUpdate = true;
                    }

                    if (produceInfo.total_bad_qty != t.TotalBadQty)
                    {
                        produceInfo.total_bad_qty = t.TotalBadQty;
                        isUpdate = true;
                    }

                    if (produceInfo.total_in_user_work_hour != t.TotalInUserWorkHour)
                    {
                        produceInfo.total_in_user_work_hour = t.TotalInUserWorkHour;
                        isUpdate = true;
                    }

                    if (produceInfo.total_finish_user_work_hour != t.TotalFinishUserWorkHour)
                    {
                        produceInfo.total_finish_user_work_hour = t.TotalFinishUserWorkHour;
                        isUpdate = true;
                    }

                    if (produceInfo.total_user_qty != t.TotalUserQty)
                    {
                        produceInfo.total_user_qty = t.TotalUserQty;
                        isUpdate = true;
                    }

                    if (produceInfo.today_plan_user_qty != t.TotalPlanUserQty)
                    {
                        produceInfo.today_plan_user_qty = t.TotalPlanUserQty;
                        isUpdate = true;
                    }

                    if (produceInfo.today_work_hour != t.PlanTotalWorkHour)
                    {
                        produceInfo.today_work_hour = t.PlanTotalWorkHour;
                        isUpdate = true;
                    }

                    if (produceInfo.line_work_hour != t.LineWorkHour)
                    {
                        produceInfo.line_work_hour = t.LineWorkHour;
                        isUpdate = true;
                    }

                    if (produceInfo.oqc_send_qty != t.OqcQty)
                    {
                        produceInfo.oqc_send_qty = t.OqcQty;
                        isUpdate = true;
                    }

                    if (produceInfo.delay_plan_qty != t.PlanDelayQty)
                    {
                        produceInfo.delay_plan_qty = t.PlanDelayQty;
                        isUpdate = true;
                    }

                    if (produceInfo.plan_total_total_work_hour != t.PlanTotalTotalWorkHour)
                    {
                        produceInfo.plan_total_total_work_hour = t.PlanTotalTotalWorkHour;
                        isUpdate = true;
                    }

                    if (produceInfo.other_standard_time != t.OtherStandardTime)
                    {
                        produceInfo.other_standard_time = t.OtherStandardTime;
                        isUpdate = true;
                    }

                    if (produceInfo.other_total_work_hour != t.OtherTotalWorkHour)
                    {
                        produceInfo.other_total_work_hour = t.OtherTotalWorkHour;
                        isUpdate = true;
                    }

                    if (produceInfo.total_in_user_attend_hour != t.TotalInUserAttendHour)
                    {
                        produceInfo.total_in_user_attend_hour = t.TotalInUserAttendHour;
                        isUpdate = true;
                    }

                    if (produceInfo.total_finish_user_attend_hour != t.TotalFinishUserAttendHour)
                    {
                        produceInfo.total_finish_user_attend_hour = t.TotalFinishUserAttendHour;
                        isUpdate = true;
                    }

                    if (produceInfo.line_name != t.LineName)
                    {
                        produceInfo.line_name = t.LineName;
                        isUpdate = true;
                    }

                    if (produceInfo.line_name_en != trans?.TranValue)
                    {
                        produceInfo.line_name_en = trans?.TranValue;
                        isUpdate = true;
                    }

                    if (produceInfo.plan_total_finish_pcs_qty != t.TargetPCSQty)
                    {
                        produceInfo.plan_total_finish_pcs_qty = t.TargetPCSQty;
                        isUpdate = true;
                    }

                    if (isUpdate)
                    {
                        updateList.Add(produceInfo);
                    }
                }
            });

            await this.statsDataRepository.CommitChangesByCommonAsync(() =>
            {
                this.statsDataRepository.CommonRepository.AddEntities(addList);
                this.statsDataRepository.CommonRepository.UpdateEntities(updateList);
            });

            return true;
        }

        /// <summary>
        /// 同步齐套
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        public async Task<bool> SyncOweAsync(List<SyncWorkOweStatisModel> model)
        {
            if (!model.Any())
            {
                return true;
            }

            var currDate = model.FirstOrDefault()?.CurrDate;
            var orgId = model.FirstOrDefault()?.OrgId;
            var oweList = await this.statsDataRepository.CommonRepository.GetEntitiesAsync<t_owe>(t => t.curr_date == currDate && t.org_id == orgId);
            List<t_owe> addList = new List<t_owe>();
            List<t_owe> updateList = new List<t_owe>();
            var translate = await this.RetryTranslateAsync(model.Select(t => t.LineName).Distinct().ToList());
            foreach (var owe in model)
            {
                var oweInfo = oweList.FirstOrDefault(f => f.time == owe.Time && f.curr_date == owe.CurrDate && f.line_code == owe.LineCode && f.work_code == owe.WorkCode);
                var trans = translate?.Details?.FirstOrDefault(t => t.SrcValue == owe.LineName);
                if (oweInfo == null)
                {
                    oweInfo = new t_owe()
                    {
                        line_code = owe.LineCode,
                        line_name = owe.LineName,
                        line_name_en = trans?.TranValue,
                        org_id = orgId,
                        curr_date = owe.CurrDate,
                        is_owe = owe.IsOwe,
                        owe_qty = owe.OweQty,
                        qty = owe.Qty,
                        work_code = owe.WorkCode,
                        time = owe.Time,
                    };

                    this.SetEntityId(oweInfo);

                    addList.Add(oweInfo);
                }
                else
                {
                    bool isUpdate = false;
                    if (oweInfo.is_owe != owe.IsOwe)
                    {
                        oweInfo.is_owe = owe.IsOwe;
                        isUpdate = true;
                    }

                    if (oweInfo.owe_qty != owe.OweQty)
                    {
                        oweInfo.owe_qty = owe.OweQty;
                        isUpdate = true;
                    }

                    if (oweInfo.qty != owe.Qty)
                    {
                        oweInfo.qty = owe.Qty;
                        isUpdate = true;
                    }

                    if (string.IsNullOrEmpty(oweInfo.line_name_en))
                    {
                        oweInfo.line_name_en = trans?.TranValue;
                        isUpdate = true;
                    }

                    if (string.IsNullOrEmpty(oweInfo.line_name))
                    {
                        oweInfo.line_name = owe.LineName;
                        isUpdate = true;
                    }

                    if (isUpdate)
                    {
                        updateList.Add(oweInfo);
                    }
                }
            }

            await this.statsDataRepository.CommitChangesByCommonAsync(() =>
            {
                this.statsDataRepository.CommonRepository.AddEntities(addList);
                this.statsDataRepository.CommonRepository.UpdateEntities(updateList);
            });

            return true;
        }

        /// <summary>
        /// 同步验货数据
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        public async Task<bool> SyncShipmentAsync(List<TimeShippmentModel> model)
        {
            var beginDate = DateTime.Parse(model.Min(t => t.Time));
            var endDate = DateTime.Parse(model.Max(t => t.Time));
            var orgId = model.Max(t => t.OrgId);
            var shipmentList = await this.statsDataRepository.CommonRepository.GetEntitiesAsync<t_shipment>(t => t.curr_date >= beginDate && t.curr_date <= endDate && t.org_id == orgId);
            List<t_shipment> addList = new List<t_shipment>();
            List<t_shipment> updateList = new List<t_shipment>();

            model.ForEach(t =>
            {
                t.Details.ForEach(s =>
                {
                    var date = DateTime.Parse(t.Time);
                    s.LineCodes.ForEach(l =>
                    {
                        var shipmentInfo = shipmentList.FirstOrDefault(f => f.curr_date == date && f.line_code == l && f.pdt_no == s.Code);

                        if (shipmentInfo == null)
                        {
                            shipmentInfo = new t_shipment()
                            {
                                line_code = l,
                                org_id = orgId,
                                curr_date = date,
                                pdt_no = s.Code,
                                qty = s.Qty,
                                finisi_qty = s.FinisiQty,
                            };

                            this.SetEntityId(shipmentInfo);

                            addList.Add(shipmentInfo);
                        }
                        else
                        {
                            bool isUpdate = false;
                            if (shipmentInfo.qty != s.Qty)
                            {
                                shipmentInfo.qty = s.Qty;
                                isUpdate = true;
                            }

                            if (shipmentInfo.finisi_qty != s.FinisiQty)
                            {
                                shipmentInfo.finisi_qty = s.FinisiQty;
                                isUpdate = true;
                            }

                            if (isUpdate)
                            {
                                updateList.Add(shipmentInfo);
                            }
                        }
                    });
                });
            });

            await this.statsDataRepository.CommitChangesByCommonAsync(() =>
            {
                this.statsDataRepository.CommonRepository.AddEntities(addList);
                this.statsDataRepository.CommonRepository.UpdateEntities(updateList);
            });

            return true;
        }

        /// <summary>
        /// 同步FPY
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        public async Task<bool> SyncFPYAsync(List<FPYModel> model)
        {
            var beginDate = model.Min(t => t.Date);
            var endDate = model.Max(t => t.Date);
            var orgId = model.Max(t => t.OrgId);
            var fpyList = await this.statsDataRepository.CommonRepository.GetEntitiesAsync<t_fpy>(t => t.curr_date >= beginDate && t.curr_date <= endDate && t.org_id == orgId);
            List<t_fpy> addList = new List<t_fpy>();
            List<t_fpy> updateList = new List<t_fpy>();
            var translate = await this.RetryTranslateAsync(model.Where(t => !string.IsNullOrEmpty(t.LineName)).Select(t => t.LineName).Distinct().ToList());
            model.ForEach(t =>
            {
                var fpyInfo = fpyList.FirstOrDefault(f => f.curr_date == t.Date && f.line_code == t.LineCode && f.procedure_code == t.ProcedureCode);
                var tran = translate?.Details?.FirstOrDefault(x => x.SrcValue == t.LineName);
                if (fpyInfo == null)
                {
                    fpyInfo = new t_fpy()
                    {
                        line_code = t.LineCode,
                        org_id = orgId,
                        curr_date = t.Date,
                        qty = t.BookingQty,
                        line_name = t.LineName,
                        line_name_en = tran?.TranValue,
                        procedure_code = t.ProcedureCode,
                    };

                    this.SetEntityId(fpyInfo);
                    addList.Add(fpyInfo);
                }
                else
                {
                    bool isUpdate = false;

                    if (fpyInfo.qty != t.BookingQty)
                    {
                        fpyInfo.qty = t.BookingQty;
                        isUpdate = true;
                    }

                    if (string.IsNullOrEmpty(fpyInfo.line_name_en))
                    {
                        fpyInfo.line_name_en = tran?.TranValue;
                        isUpdate = true;
                    }

                    if (string.IsNullOrEmpty(fpyInfo.line_name))
                    {
                        fpyInfo.line_name = t.LineName;
                        isUpdate = true;
                    }

                    if (isUpdate)
                    {
                        updateList.Add(fpyInfo);
                    }
                }
            });

            await this.statsDataRepository.CommitChangesByCommonAsync(() =>
            {
                this.statsDataRepository.CommonRepository.AddEntities(addList);
                this.statsDataRepository.CommonRepository.UpdateEntities(updateList);
            });

            return true;
        }

        /// <summary>
        /// 同步经营目标
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        public async Task<bool> SyncObjectiveAsync(List<OperatingObjectiveModel> model)
        {
            List<t_operating_objective> addList = new List<t_operating_objective>();
            List<t_operating_objective> updateList = new List<t_operating_objective>();
            var orgId = model.FirstOrDefault()?.OrgId;
            var apiParam = new ApiParam(orgId);

            foreach (var m in model)
            {
                var obj = await this.statsDataRepository.CommonRepository.GetEntityAsync<t_operating_objective>(apiParam, t => t.time.Date == m.Time.Date && t.depart_id == m.DepartId);
                if (obj == null)
                {
                    obj = new t_operating_objective()
                    {
                        upph = m.Upph,
                        org_id = m.OrgId,
                        time = m.Time,
                        per_output_value = m.PerOutputValue,
                        direct_manufacture_rate = m.DirectManufactureRate,
                        manufacture_overhead_rate = m.ManufactureOverheadRate,
                        total_expense = m.TotalExpense,
                        output_value = m.OutputValue,
                        in_qty = m.InQty,
                        work_days = m.WorkDays,
                        target_month_user_qty = m.TargetMonthUserQty,
                        cost_rate = m.CostRate,
                        depart_id = m.DepartId,
                        target_input_work_hour = m.TargetInputWorkHour,
                        target_otd_rate = m.TargetOTDRate,
                        target_fpy_rate = m.TargetFpyRate,
                        target_oqc_rate = m.TargetOQCRate
                    };

                    this.SetEntityId(obj);
                    addList.Add(obj);
                }
                else
                {
                    obj.upph = m.Upph;
                    obj.per_output_value = m.PerOutputValue;
                    obj.direct_manufacture_rate = m.DirectManufactureRate;
                    obj.manufacture_overhead_rate = m.ManufactureOverheadRate;
                    obj.total_expense = m.TotalExpense;
                    obj.output_value = m.OutputValue;
                    obj.in_qty = m.InQty;
                    obj.work_days = m.WorkDays;
                    obj.target_month_user_qty = m.TargetMonthUserQty;
                    obj.cost_rate = m.CostRate;
                    obj.target_input_work_hour = m.TargetInputWorkHour;
                    obj.target_otd_rate = m.TargetOTDRate;
                    obj.target_fpy_rate = m.TargetFpyRate;
                    obj.target_oqc_rate = m.TargetOQCRate;
                    updateList.Add(obj);
                }
            }

            await this.statsDataRepository.CommitChangesByCommonAsync(() =>
            {
                this.statsDataRepository.CommonRepository.AddEntities(addList);
                this.statsDataRepository.CommonRepository.UpdateEntities(updateList);
            });

            return true;
        }

        /// <summary>
        /// 同步在制工单（计划报表-在制工单明细）
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        public async Task<bool> SyncWorkInProcessAsync(List<WorkInProcessModel> model)
        {
            var orgId = model.Max(t => t.OrgId);
            var workList = await this.statsDataRepository.CommonRepository.GetEntitiesAsync<t_work>(t => !t.status && t.org_id == orgId);
            List<t_work> addList = new List<t_work>();
            List<t_work> updateList = new List<t_work>();
            var trans = await this.RetryTranslateAsync(model.Where(t => !string.IsNullOrEmpty(t.LineName)).Select(t => t.LineName).Distinct().ToList());
            model.ForEach(t =>
            {
                var workInfo = workList.FirstOrDefault(f => f.work_code == t.WorkCode);
                var tran = trans?.Details?.FirstOrDefault(x => x.SrcValue == t.LineName);
                if (workInfo == null)
                {
                    workInfo = new t_work()
                    {
                        line_code = t.LineCode,
                        line_name = t.LineName,
                        line_name_en = tran?.TranValue,
                        org_id = orgId,
                        work_code = t.WorkCode,
                        begin_date = t.BeginDate,
                        end_date = t.EndDate,
                        status = t.Status
                    };

                    this.SetEntityId(workInfo);
                    addList.Add(workInfo);
                }
                else
                {
                    bool isUpdate = false;

                    if (workInfo.status != t.Status)
                    {
                        workInfo.status = t.Status;
                        isUpdate = true;
                    }

                    if (workInfo.end_date != t.EndDate)
                    {
                        workInfo.end_date = t.EndDate;
                        isUpdate = true;
                    }

                    if (string.IsNullOrEmpty(workInfo.line_name))
                    {
                        workInfo.line_name = t.LineName;
                        isUpdate = true;
                    }

                    if (string.IsNullOrEmpty(workInfo.line_name_en))
                    {
                        workInfo.line_name_en = workInfo.line_name_en;
                        isUpdate = true;
                    }

                    if (isUpdate)
                    {
                        updateList.Add(workInfo);
                    }
                }
            });

            await this.statsDataRepository.CommitChangesByCommonAsync(() =>
            {
                this.statsDataRepository.CommonRepository.AddEntities(addList);
                this.statsDataRepository.CommonRepository.UpdateEntities(updateList);
            });

            return true;
        }

        /// <summary>
        /// 同步经营报表
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        public async Task<bool> SyncExpenseAsync(List<ExpenseModel> model)
        {
            var beginDate = model.Min(t => t.Date);
            var endDate = model.Max(t => t.Date);
            var orgId = model.Max(t => t.OrgId);
            var expenseList = await this.statsDataRepository.CommonRepository.GetEntitiesAsync<t_expense>(t => t.curr_date >= beginDate && t.curr_date <= endDate && t.org_id == orgId);
            List<t_expense> addList = new List<t_expense>();
            List<t_expense> updateList = new List<t_expense>();
            var trans = await this.RetryTranslateAsync(model.Where(t => !string.IsNullOrEmpty(t.DeptName)).Select(t => t.DeptName).Distinct().ToList());
            model.ForEach(t =>
            {
                var expenseInfo = expenseList.FirstOrDefault(f => f.curr_date == t.Date && f.dept_code == t.DeptCode);
                var tran = trans?.Details?.FirstOrDefault(x => x.SrcValue == t.DeptName);
                if (expenseInfo == null)
                {
                    expenseInfo = new t_expense()
                    {
                        dept_code = t.DeptCode,
                        dept_name = t.DeptName,
                        dept_name_en = tran?.TranValue,
                        org_id = orgId,
                        curr_date = t.Date,
                        expense = t.Expense,
                        cost = t.Cost,
                    };

                    this.SetEntityId(expenseInfo);
                    addList.Add(expenseInfo);
                }
                else
                {
                    bool isUpdate = false;

                    if (expenseInfo.expense != t.Expense)
                    {
                        expenseInfo.expense = t.Expense;
                        isUpdate = true;
                    }

                    if (expenseInfo.cost != t.Cost)
                    {
                        expenseInfo.cost = t.Cost;
                        isUpdate = true;
                    }

                    if (string.IsNullOrEmpty(expenseInfo.dept_name))
                    {
                        expenseInfo.dept_name = t.DeptName;
                        isUpdate = true;
                    }

                    if (string.IsNullOrEmpty(expenseInfo.dept_name_en))
                    {
                        expenseInfo.dept_name_en = tran?.TranValue;
                        isUpdate = true;
                    }

                    if (isUpdate)
                    {
                        updateList.Add(expenseInfo);
                    }
                }
            });

            await this.statsDataRepository.CommitChangesByCommonAsync(() =>
            {
                this.statsDataRepository.CommonRepository.AddEntities(addList);
                this.statsDataRepository.CommonRepository.UpdateEntities(updateList);
            });

            return true;
        }

        /// <summary>
        /// 同步制造率
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        public async Task<bool> SyncManufacturingRateAsync(List<ManufacturingRate> model)
        {
            var beginDate = model.Min(t => t.CurrDate);
            var endDate = model.Max(t => t.CurrDate);
            var orgId = model.Max(t => t.OrgId);
            var manuList = await this.statsDataRepository.CommonRepository.GetEntitiesAsync<t_manufacturing_rate>(t => t.curr_date >= beginDate && t.curr_date <= endDate && t.org_id == orgId);
            List<t_manufacturing_rate> addList = new List<t_manufacturing_rate>();
            List<t_manufacturing_rate> updateList = new List<t_manufacturing_rate>();

            model.ForEach(t =>
            {
                var manuInfo = manuList.FirstOrDefault(f => f.curr_date == t.CurrDate && t.LineCode == f.line_code);

                if (manuInfo == null)
                {
                    manuInfo = new t_manufacturing_rate()
                    {
                        line_code = t.LineCode,
                        org_id = orgId,
                        curr_date = t.CurrDate,
                        total_total_workHour = t.TotalTotalWorkHour,
                        total_user_work_hour = t.TotalUserWorkHour,
                    };

                    this.SetEntityId(manuInfo);
                    addList.Add(manuInfo);
                }
                else
                {
                    bool isUpdate = false;

                    if (manuInfo.total_total_workHour != t.TotalTotalWorkHour)
                    {
                        manuInfo.total_total_workHour = t.TotalTotalWorkHour;
                        isUpdate = true;
                    }

                    if (manuInfo.total_user_work_hour != t.TotalUserWorkHour)
                    {
                        manuInfo.total_user_work_hour = t.TotalUserWorkHour;
                        isUpdate = true;
                    }

                    if (isUpdate)
                    {
                        updateList.Add(manuInfo);
                    }
                }
            });

            await this.statsDataRepository.CommitChangesByCommonAsync(() =>
            {
                this.statsDataRepository.CommonRepository.AddEntities(addList);
                this.statsDataRepository.CommonRepository.UpdateEntities(updateList);
            });

            return true;
        }

        /// <summary>
        /// 同步提案
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        public async Task<bool> SyncMotionAsync(MotionModel model)
        {
            List<t_motion> addList = new List<t_motion>();
            List<t_motion> updateList = new List<t_motion>();
            ApiParam apiParam = new ApiParam(model.OrgId);
            var motionInfo = await this.statsDataRepository.CommonRepository.GetEntityAsync<t_motion>(apiParam, t => t.org_id == model.OrgId && t.code == model.Code);
            if (motionInfo == null)
            {
                motionInfo = new t_motion()
                {
                    dept_code = model.Department,
                    org_id = model.OrgId,
                    motion_date = model.MotionDate,
                    benefit = model.Benefit,
                    code = model.Code,
                    status = model.Status,
                    name = model.Name,
                    category = model.Category,
                    user_code = model.Motioner
                };

                this.SetEntityId(motionInfo);
                addList.Add(motionInfo);
            }
            else
            {
                bool isUpdate = false;

                if (motionInfo.benefit != model.Benefit)
                {
                    motionInfo.benefit = model.Benefit;
                    isUpdate = true;
                }

                if (motionInfo.status != model.Status)
                {
                    motionInfo.status = model.Status;
                    isUpdate = true;
                }

                if (isUpdate)
                {
                    updateList.Add(motionInfo);
                }
            }

            await this.statsDataRepository.CommitChangesByCommonAsync(() =>
            {
                this.statsDataRepository.CommonRepository.AddEntities(addList);
                this.statsDataRepository.CommonRepository.UpdateEntities(updateList);
            });

            return true;
        }

        /// <summary>
        /// 同步超领
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        public async Task<bool> SyncExceedAsync(ExceedModel model)
        {
            List<t_exceed> addList = new List<t_exceed>();
            ApiParam apiParam = new ApiParam(model.OrgId);
            var exceedInfo = await this.statsDataRepository.CommonRepository.GetEntityAsync<t_exceed>(apiParam, t => t.org_id == model.OrgId && t.code == model.Code);
            List<t_exceed_detail> details = new List<t_exceed_detail>();

            if (exceedInfo == null)
            {
                exceedInfo = new t_exceed
                {
                    code = model.Code,
                    applicanter = model.Applicanter,
                    applicant_date = model.ApplicantDate,
                    manager = model.Manager,
                    dept_code = model.Department,
                    org_id = model.OrgId
                };

                this.SetEntityId(exceedInfo);
                addList.Add(exceedInfo);

                foreach (var detail in model.Details)
                {
                    var motionDetail = new t_exceed_detail
                    {
                        org_id = model.OrgId,
                        exceed_id = exceedInfo.id,
                        type = detail.Type,
                        source_no = detail.SourceNo,
                        order_qty = detail.OrderQty,
                        item_no = detail.ItemNo,
                        item_desc = detail.ItemDesc,
                        qty = detail.Qty,
                        department = detail.Department,
                        price = detail.Price,
                        product_no = detail.ProductNo
                    };

                    details.Add(motionDetail);
                    this.SetEntityId(motionDetail, exceedInfo.id);
                }
            }

            await this.statsDataRepository.CommitChangesByCommonAsync(() =>
            {
                this.statsDataRepository.CommonRepository.AddEntities(addList);
                this.statsDataRepository.CommonRepository.AddEntities(details);
            });

            return true;
        }

        /// <summary>
        /// 同步OEE数据
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        public async Task<bool> SyncOeeAsync(List<OEEParamModel> model)
        {
            if (model != null && model.Any())
            {
                List<t_oee> addList = new List<t_oee>();
                List<t_oee> updateList = new List<t_oee>();
                var orgId = model.FirstOrDefault()?.OrgId;
                ApiParam apiParam = new ApiParam(orgId);
                foreach (var item in model)
                {
                    var oee = await this.statsDataRepository.CommonRepository.GetEntityAsync<t_oee>(apiParam, t => t.org_id == item.OrgId && t.times == item.Times && t.liableLine == item.LiableLine);
                    if (oee == null)
                    {
                        oee = new t_oee()
                        {
                            abno_time = item?.AbnoTime ?? 0,
                            stand_by_time = item?.StandByTime ?? 0,
                            times = item?.Times ?? DateTime.Now,
                            colse_time = item.CloseTime ?? 0,
                            time_pcs = item.TimePcs ?? 0,
                            crop_rate = item.CropRate ?? 0,
                            fpy = item.Fpy ?? 0,
                            performance = item.Performance ?? 0,
                            oee = item.OEE ?? 0,
                            liableDept = item.LiableDept,
                            liableLine = item.LiableLine,
                            org_id = item.OrgId
                        };
                        this.SetEntityId(oee);
                        addList.Add(oee);
                    }
                    else
                    {
                        oee.abno_time = item?.AbnoTime ?? 0;
                        oee.stand_by_time = item?.StandByTime ?? 0;
                        oee.colse_time = item?.CloseTime ?? 0;
                        oee.time_pcs = item?.TimePcs ?? 0;
                        oee.crop_rate = item?.CropRate ?? 0;
                        oee.fpy = item?.Fpy ?? 0;
                        oee.performance = item?.Performance ?? 0;
                        oee.oee = item?.OEE ?? 0;
                        updateList.Add(oee);
                    }
                }

                await this.statsDataRepository.CommitChangesByCommonAsync(() =>
                {
                    this.statsDataRepository.CommonRepository.AddEntities(addList);
                    this.statsDataRepository.CommonRepository.UpdateEntities(updateList);
                });
            }

            return true;
        }

        /// <summary>
        /// 同步Otd数据
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        public async Task<bool> SyncOtdAsync(List<ODTParamModel> model)
        {
            LibCheckNullUtils.CheckNull(model, "model");
            if (!model.Any())
            {
                return true;
            }

            var orgId = model.FirstOrDefault()?.OrgId;
            var time = model.FirstOrDefault()?.CurrDate;
            var apiParam = new ApiParam(orgId);
            var otds = await this.statsDataRepository.CommonRepository.GetEntitiesAsync<t_otd>(apiParam, t => t.org_id == orgId && t.curr_date == time);
            List<t_otd> addList = new List<t_otd>();
            List<t_otd> updateList = new List<t_otd>();

            foreach (var m in model)
            {
                var otd = otds.FirstOrDefault(t => t.org_id == m.OrgId && t.curr_date == m.CurrDate && t.line_code == m.LineCode);

                if (otd == null)
                {
                    otd = new t_otd()
                    {
                        org_id = m.OrgId,
                        curr_date = m.CurrDate,
                        yes_otd_qty = m.YesOtdQty,
                        no_otd_qty = m.NoOtdQty,
                        total_otd_qty = m.TotalOtdQty,
                        line_code = m.LineCode
                    };
                    this.SetEntityId(otd);
                    addList.Add(otd);
                }
                else
                {
                    otd.yes_otd_qty = m.YesOtdQty;
                    otd.no_otd_qty = m.NoOtdQty;
                    otd.total_otd_qty = m.TotalOtdQty;
                    updateList.Add(otd);
                }
            }

            await this.statsDataRepository.CommitChangesByCommonAsync(() =>
            {
                this.statsDataRepository.CommonRepository.AddEntities(addList);
                this.statsDataRepository.CommonRepository.UpdateEntities(updateList);
            });
            return true;
        }

        /// <summary>
        /// 层级看板 - 安全管理 - 安全录入 - 同步
        /// </summary>
        /// <param name="models"></param>
        /// <returns></returns>
        public async Task<bool> SyncLineSafetyAsync(List<LineSafetySyncModel> models)
        {
            if (models == null || !models.Any())
            {
                return true;
            }

            var lineTrans = await this.RetryTranslateAsync(models.Select(t => t.LineName).Distinct().ToList());
            var orgId = models.FirstOrDefault().OrgId;
            var lineCodes = models.Select(x => x.LineCode).Distinct().ToList();
            var minTime = models.Select(x => x.Time).Min();
            var maxTime = models.Select(x => x.Time).Max();

            var apiParam = new ApiParam(orgId);
            var entities = await this.statsDataRepository.CommonRepository.GetEntitiesAsync<t_bi_line_safety>(apiParam, t => t.org_id == orgId && t.time >= minTime && t.time <= maxTime && lineCodes.Contains(t.line_code));

            var toAdd = new List<t_bi_line_safety>();
            var toUpdate = new List<t_bi_line_safety>();

            foreach (var m in models)
            {
                var entity = entities.Where(x => x.org_id == m.OrgId && x.line_code == m.LineCode && x.time == m.Time).FirstOrDefault();
                var tran = lineTrans?.Details?.FirstOrDefault(t => t.SrcValue == m.LineName);
                if (entity == null)
                {
                    entity = new t_bi_line_safety()
                    {
                        org_id = orgId,
                    };

                    this.SetEntityId(entity);
                    toAdd.Add(entity);
                }
                else
                {
                    toUpdate.Add(entity);
                }

                entity.line_code = m.LineCode;
                entity.time = m.Time;
                entity.remark = m.Remark;
                entity.is_abnormal = m.IsAbnormal;
                entity.safety_status = m.SafetyStatus;
                entity.line_name = m.LineName;
                entity.line_name_en = tran?.TranValue;
            }

            await this.statsDataRepository.CommitChangesByCommonAsync(() =>
            {
                this.statsDataRepository.CommonRepository.AddEntities(toAdd);
                this.statsDataRepository.CommonRepository.UpdateEntities(toUpdate);
            });

            return true;
        }

        /// <summary>
        /// 层级看板 - 问题跟踪 - 同步
        /// </summary>
        /// <param name="models"></param>
        /// <returns></returns>
        public async Task<bool> SyncTierWipIssueRecordAsync(List<TierWipIssueRecordSyncModel> models)
        {
            if (models == null || !models.Any())
            {
                return true;
            }

            var strs = new List<string>();

            strs.AddRange(models.Where(t => !string.IsNullOrEmpty(t.LineName)).Select(t => t.LineName).Distinct());
            strs.AddRange(models.Where(t => !string.IsNullOrEmpty(t.ShopDepartName)).Select(t => t.ShopDepartName).Distinct());
            strs.AddRange(models.Where(t => !string.IsNullOrEmpty(t.Solution)).Select(t => t.Solution).Distinct());
            strs.AddRange(models.Where(t => !string.IsNullOrEmpty(t.Description)).Select(t => t.Description).Distinct());
            strs.AddRange(models.Where(t => !string.IsNullOrEmpty(t.StatusName)).Select(t => t.StatusName).Distinct());
            var trans = await this.RetryTranslateAsync(strs);

            var orgId = models.FirstOrDefault().OrgId;
            var ids = models.Select(x => x.Id).ToList();

            var apiParam = new ApiParam(orgId);
            var entities = await this.statsDataRepository.CommonRepository.GetEntitiesAsync<t_bi_wip_issue_record>(apiParam, t => t.org_id == orgId && ids.Contains(t.id));

            var toAdd = new List<t_bi_wip_issue_record>();
            var toUpdate = new List<t_bi_wip_issue_record>();

            foreach (var m in models)
            {
                var entity = entities.Where(x => x.id == m.Id).FirstOrDefault();
                var lineTran = trans?.Details?.FirstOrDefault(t => t.SrcValue == m.LineName);
                var deptTran = trans?.Details?.FirstOrDefault(t => t.SrcValue == m.ShopDepartName);
                var solTran = trans?.Details?.FirstOrDefault(t => t.SrcValue == m.Solution);
                var descTran = trans?.Details?.FirstOrDefault(t => t.SrcValue == m.Description);
                var statusTran = trans?.Details?.FirstOrDefault(t => t.SrcValue == m.StatusName);
                if (entity == null)
                {
                    entity = new t_bi_wip_issue_record()
                    {
                        id = m.Id,
                        org_id = orgId,
                    };

                    toAdd.Add(entity);
                }
                else
                {
                    toUpdate.Add(entity);
                }

                entity.issue_time = m.IssueTime;
                entity.charge_user_code = m.ChargeUserCode;
                entity.charge_user_name = m.ChargeUserName;
                entity.close_time = m.CloseTime;
                entity.close_user_code = m.CloseUserCode;
                entity.close_user_name = m.CloseUserName;
                entity.complete_time = m.CompleteTime;
                entity.create_user_code = m.CreateUserCode;
                entity.status_name_en = statusTran?.TranValue;
                entity.create_user_name = m.CreateUserName;
                entity.description = m.Description;
                entity.line_code = m.LineCode;
                entity.line_name = m.LineName;
                entity.shop_depart_code = m.ShopDepartCode;
                entity.shop_depart_name = m.ShopDepartName;
                entity.shop_depart_name_en = deptTran?.TranValue;
                entity.description_en = descTran?.TranValue;
                entity.solution_en = solTran?.TranValue;
                entity.line_name_en = lineTran?.TranValue;
                entity.solution = m.Solution;
                entity.status = m.Status;
                entity.status_name = m.StatusName;
            }

            await this.statsDataRepository.CommitChangesByCommonAsync(() =>
            {
                this.statsDataRepository.CommonRepository.AddEntities(toAdd);
                this.statsDataRepository.CommonRepository.UpdateEntities(toUpdate);
            });

            return true;
        }

        /// <summary>
        /// 层级看板 - 直接人员出勤 - 同步
        /// </summary>
        /// <param name="models"></param>
        /// <returns></returns>
        public async Task<bool> SyncTierDepartmentAttendanceAsync(List<TierDepartmentAttendanceSyncModel> models)
        {
            if (models == null || !models.Any())
            {
                return true;
            }

            var orgId = models.FirstOrDefault().OrgId;
            var ids = models.Select(x => x.Id).ToList();

            var apiParam = new ApiParam(orgId);
            var entities = await this.statsDataRepository.CommonRepository.GetEntitiesAsync<t_bi_depart_attendance>(apiParam, t => t.org_id == orgId && ids.Contains(t.id));

            var toAdd = new List<t_bi_depart_attendance>();
            var toUpdate = new List<t_bi_depart_attendance>();

            foreach (var m in models)
            {
                var entity = entities.Where(x => x.id == m.Id).FirstOrDefault();

                if (entity == null)
                {
                    entity = new t_bi_depart_attendance()
                    {
                        id = m.Id,
                        org_id = orgId,
                    };

                    toAdd.Add(entity);
                }
                else
                {
                    toUpdate.Add(entity);
                }

                entity.class_id = m.ClassId;
                entity.department_code = m.DepartmentCode;
                entity.time = m.Time;
                entity.employee_count = m.EmployeeCount;
                entity.present_employee_count = m.PresentEmployeeCount;
                entity.new_employee_count = m.NewEmployeeCount;
                entity.leave_employee_count = m.LeaveEmployeeCount;
            }

            await this.statsDataRepository.CommitChangesByCommonAsync(() =>
            {
                this.statsDataRepository.CommonRepository.AddEntities(toAdd);
                this.statsDataRepository.CommonRepository.UpdateEntities(toUpdate);
            });

            return true;
        }

        /// <summary>
        /// 同步andon数据
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        public async Task<bool> SyncAndonDataAsync(List<AndonSyncModel> model)
        {
            LibCheckNullUtils.CheckNull(model, "model");
            if (!model.Any())
            {
                return true;
            }

            var orgId = model.FirstOrDefault()?.OrgId;
            var apiParam = new ApiParam(orgId);
            var addList = new List<t_andon_data>();
            var updateList = new List<t_andon_data>();
            var strs = new List<string>();
            strs.AddRange(model.Where(t => !string.IsNullOrEmpty(t.IType)).Select(t => t.IType).Distinct().ToList());
            strs.AddRange(model.Where(t => !string.IsNullOrEmpty(t.IpType)).Select(t => t.IpType).Distinct().ToList());
            strs.AddRange(model.Where(t => !string.IsNullOrEmpty(t.LineName)).Select(t => t.LineName).Distinct().ToList());
            strs.AddRange(model.Where(t => !string.IsNullOrEmpty(t.IRemark)).Select(t => t.IRemark).Distinct().ToList());
            var trans = await this.RetryTranslateAsync(strs);
            foreach (var m in model)
            {
                var data = await this.statsDataRepository.CommonRepository.GetEntityAsync<t_andon_data>(apiParam, t => t.org_id == m.OrgId && t.curr_date == m.TDate && t.line_code == m.ILine && t.i_type == m.IType && t.ip_type == m.IpType && t.i_remark == m.IRemark);
                var t = trans?.Details?.FirstOrDefault(t => t.SrcValue == m.IType);
                var t1 = trans?.Details?.FirstOrDefault(x => x.SrcValue == m.IpType);
                var t2 = trans?.Details?.FirstOrDefault(x => x.SrcValue == m.LineName);
                var t3 = trans?.Details?.FirstOrDefault(x => x.SrcValue == m.IRemark);
                if (data == null)
                {
                    data = new t_andon_data()
                    {
                        curr_date = m.TDate,
                        line_code = m.ILine,
                        line_name = m.LineName,
                        line_name_en = t2?.TranValue,
                        i_type = m.IType,
                        i_type_en = t?.TranValue,
                        ip_type = m.IpType,
                        ip_type_en = t1?.TranValue,
                        i_remark = m.IRemark,
                        i_remark_en = t3?.TranValue,
                        org_id = orgId,
                        a_sum = m?.ASum ?? 0,
                        a_num = m?.ANum ?? 0,
                    };
                    this.SetEntityId(data);
                    addList.Add(data);
                }
                else
                {
                    var isUpdate = false;
                    if (data.a_sum != m.ASum)
                    {
                        isUpdate = true;
                        data.a_sum = m?.ASum ?? 0;
                    }

                    if (data.a_num != m.ANum)
                    {
                        isUpdate = true;
                        data.a_num = m?.ANum ?? 0;
                    }

                    if (data.line_name != m.LineName)
                    {
                        data.line_name = m.LineName;
                        isUpdate = true;
                    }

                    if (string.IsNullOrEmpty(data.line_name_en))
                    {
                        data.line_name_en = t2?.TranValue;
                        isUpdate = true;
                    }

                    if (string.IsNullOrEmpty(data.i_remark_en))
                    {
                        data.i_remark_en = t3?.TranValue;
                        isUpdate = true;
                    }

                    if (string.IsNullOrEmpty(data.i_type_en))
                    {
                        data.i_type_en = t?.TranValue;
                        isUpdate = true;
                    }

                    if (string.IsNullOrEmpty(data.ip_type_en))
                    {
                        data.ip_type_en = t1?.TranValue;
                        isUpdate = true;
                    }

                    if (isUpdate)
                    {
                        updateList.Add(data);
                    }
                }
            }

            await this.statsDataRepository.CommitChangesByCommonAsync(() =>
            {
                this.statsDataRepository.CommonRepository.AddEntities(addList);
                this.statsDataRepository.CommonRepository.UpdateEntities(updateList);
            });
            return true;
        }

        /// <summary>
        /// 同步出货验货数据
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        public async Task<bool> SyncShipmentExamineAsync(List<SyncShipmentExamineResultModel> models)
        {
            if (!models.Any())
            {
                return true;
            }

            var addList = new List<t_shipment_examine>();
            var updateList = new List<t_shipment_examine>();
            var orgId = models.FirstOrDefault()?.OrgId;
            var apiParam = new ApiParam(orgId);
            var tran = await this.RetryTranslateAsync(models.Select(t => t.LineName).Distinct().ToList());
            foreach (var model in models)
            {
                var existedshipex = await this.statsDataRepository.CommonRepository.GetEntityAsync<t_shipment_examine>(apiParam, t => t.org_id == model.OrgId && t.work_code == model.WorkCode && t.line_code == model.LineCode);
                var lineTran = tran?.Details?.FirstOrDefault(t => t.SrcValue == model.LineName);
                if (existedshipex == null)
                {
                    existedshipex = new t_shipment_examine()
                    {
                        org_id = orgId,
                        line_name = model.LineName,
                        line_name_en = lineTran?.TranValue,
                        shipment_time = model.ShipmentTime,
                        examine_time = model.ExamineTime,
                        work_code = model.WorkCode,
                        line_code = model.LineCode,
                    };
                    this.SetEntityId(existedshipex);
                    addList.Add(existedshipex);
                }
                else
                {
                    existedshipex.shipment_time = model.ShipmentTime;
                    existedshipex.examine_time = model.ExamineTime;
                    existedshipex.line_name = model.LineName;
                    existedshipex.line_name_en = lineTran?.TranValue;
                    updateList.Add(existedshipex);
                }
            }

            await this.statsDataRepository.CommitChangesByCommonAsync(() =>
            {
                this.statsDataRepository.CommonRepository.AddEntities(addList);
                this.statsDataRepository.CommonRepository.UpdateEntities(updateList);
            });
            return true;
        }

        /// <summary>
        /// 在制工单同步
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        public async Task<bool> SyncInProcessWorkAsync(List<WorkInProcessSyncModel> model)
        {
            if (!model.Any())
            {
                return true;
            }

            var orgId = model.FirstOrDefault()?.OrgId;
            var apiParam = new ApiParam(orgId);
            var modelIds = model.Select(x => x.WorkCode).Distinct().ToList();
            var time = model.FirstOrDefault()?.Time;
            var lineTrans = await this.RetryTranslateAsync(model.Where(t => !string.IsNullOrEmpty(t.LineName)).Select(t => t.LineName).Distinct().ToList());
            var listIndcludes = await this.statsDataRepository.CommonRepository.GetEntitiesAsync<t_in_process_work>(apiParam, t => t.org_id == orgId && modelIds.Contains(t.work_code) && t.curr_date == time);
            var addList = new List<t_in_process_work>();
            var updateList = new List<t_in_process_work>();

            foreach (var m in model)
            {
                var ex = listIndcludes.FirstOrDefault(t => t.work_code == m.WorkCode && m.Time == t.curr_date);
                var tran = lineTrans?.Details?.FirstOrDefault(t => t.SrcValue == m.LineName);
                if (ex == null)
                {
                    ex = new t_in_process_work()
                    {
                        org_id = m.OrgId,
                        line_code = m.LineCode,
                        line_name = m.LineName,
                        line_name_en = tran?.TranValue,
                        work_code = m.WorkCode,
                        curr_date = m.Time,
                        work_qty = m.WorkQty,
                        work_publish_time = m.WorkPublishTime,
                        work_output_qty = m.WorkOutputQty,
                        work_output_diff_qty = m.WorkOutputDiffQty,
                        work_material_send_begin_time = m.WorkMaterialSendBeginTime,
                        pdt_sap_gmps_time = m.PdtSapGmpsTime,
                        wip_day_pdt_material = m.WipDayPdtMaterial,
                        work_start_time = m.WorkStartTime,
                        work_plan_date = m.WorkPlanDate,
                        work_warehourse_diff_qty = m.WorkWarehourseDiffQty,
                        work_warehourse_qty = m.WorkWarehourseQty,
                        wip_day_booking = m.WipDayBooking,
                        first_booking_time = m.FirstBookingTime,
                        customer_product_code = m.CustomerProductCode
                    };
                    this.SetEntityId(ex);
                    addList.Add(ex);
                }
                else
                {
                    ex.work_qty = m.WorkQty;
                    ex.work_output_qty = m.WorkOutputQty;
                    ex.work_output_diff_qty = m.WorkOutputDiffQty;
                    ex.wip_day_pdt_material = m.WipDayPdtMaterial;
                    ex.work_start_time = m.WorkStartTime;
                    ex.work_plan_date = m.WorkPlanDate;
                    ex.work_warehourse_diff_qty = m.WorkWarehourseDiffQty;
                    ex.work_warehourse_qty = m.WorkWarehourseQty;
                    ex.wip_day_booking = m.WipDayBooking;
                    ex.first_booking_time = m.FirstBookingTime;
                    ex.customer_product_code = m.CustomerProductCode;
                    ex.line_name = m.LineName;
                    ex.line_name_en = tran?.TranValue;
                    updateList.Add(ex);
                }
            }

            await this.statsDataRepository.CommitChangesByCommonAsync(() =>
            {
                this.statsDataRepository.CommonRepository.AddEntities(addList);
                this.statsDataRepository.CommonRepository.UpdateEntities(updateList);
            });
            return true;
        }

        public async Task<bool> SyncLineFpyAsync(List<SyncLineFpyModel> models)
        {
            if (models == null || !models.Any())
            {
                return true;
            }

            var addList = new List<t_line_fpy>();
            var updateList = new List<t_line_fpy>();
            var orgId = models.FirstOrDefault()?.OrgId;
            var apiParam = new ApiParam(orgId);
            var startTime = models.Min(t => t.CurrDate);
            var endTime = models.Max(t => t.CurrDate);
            var listLineFpys = await this.statsDataRepository.CommonRepository.GetEntitiesAsync<t_line_fpy>(apiParam, t => t.org_id == orgId && t.curr_date >= startTime && t.curr_date <= endTime);
            var strs = new List<string>();
            strs.AddRange(models.Where(t => !string.IsNullOrEmpty(t.LineName)).Select(t => t.LineName).Distinct().ToList());
            strs.AddRange(models.Where(t => !string.IsNullOrEmpty(t.ProcedureTopBad)).Select(t => t.ProcedureTopBad).Distinct().ToList());
            var lineTrans = await this.RetryTranslateAsync(strs);
            foreach (var model in models)
            {
                var lineFpy = listLineFpys.FirstOrDefault(t => t.curr_date == model.CurrDate && t.line_code == model.LineCode);
                var tran = lineTrans?.Details?.FirstOrDefault(t => t.SrcValue == model.LineName);
                var tran2 = lineTrans?.Details?.FirstOrDefault(t => t.SrcValue == model.ProcedureTopBad);
                if (lineFpy == null)
                {
                    lineFpy = new t_line_fpy()
                    {
                        curr_date = model.CurrDate,
                        actual_value = model.ActualValue,
                        target_value = model.TargetValue,
                        line_code = model.LineCode,
                        line_name_en = tran?.TranValue,
                        line_name = model.LineName,
                        procedure_top_bad_en = tran2?.TranValue,
                        procedure_top_bad = model.ProcedureTopBad,
                        org_id = model.OrgId
                    };
                    this.SetEntityId(lineFpy);
                    addList.Add(lineFpy);
                }
                else
                {
                    lineFpy.line_name_en = tran?.TranValue;
                    lineFpy.procedure_top_bad_en = tran2?.TranValue;
                    lineFpy.actual_value = model.ActualValue;
                    lineFpy.target_value = model.TargetValue;
                    lineFpy.procedure_top_bad = model.ProcedureTopBad;
                    lineFpy.org_id = model.OrgId;
                    updateList.Add(lineFpy);
                }
            }

            await this.statsDataRepository.CommitChangesByCommonAsync(() =>
            {
                this.statsDataRepository.CommonRepository.AddEntities(addList);
                this.statsDataRepository.CommonRepository.UpdateEntities(updateList);
            });

            return true;
        }

        public async Task<bool> SyncLineKpiStatisAsync(List<SyncLineKpiModel> models)
        {
            if (models == null || !models.Any())
            {
                return true;
            }

            var addList = new List<t_kpi_statis>();
            var updateList = new List<t_kpi_statis>();
            var time = models.FirstOrDefault()?.CurrDate;
            var orgId = models.FirstOrDefault()?.OrgId;
            var apiParam = new ApiParam(orgId);
            var kpiStatis = await this.statsDataRepository.CommonRepository.GetEntitiesAsync<t_kpi_statis>(apiParam, t => t.org_id == orgId && t.curr_date == time) ?? new List<t_kpi_statis>();
            var strs = new List<string>();
            strs.AddRange(models.Where(t => !string.IsNullOrEmpty(t.LineName)).Select(t => t.LineName).Distinct().ToList());
            strs.AddRange(models.Where(t => !string.IsNullOrEmpty(t.Title)).Select(t => t.Title).Distinct().ToList());
            strs.AddRange(models.Where(t => !string.IsNullOrEmpty(t.ProcedureName)).Select(t => t.ProcedureName).Distinct().ToList());
            strs.AddRange(models.Where(t => !string.IsNullOrEmpty(t.DateType)).Select(t => t.DateType).Distinct().ToList());
            var trans = await this.RetryTranslateAsync(strs);
            foreach (var kpi in models)
            {
                Expression<Func<t_kpi_statis, bool>> expression = t => t.line_code == kpi.LineCode && t.curr_date == kpi.CurrDate && kpi.Title == t.title && t.org_id == kpi.OrgId && t.date_type == kpi.DateType;
                //// FPY
                if (!string.IsNullOrEmpty(kpi.ProcedureName))
                {
                    expression = expression.And(t => t.procedure_name == kpi.ProcedureName);
                }

                var lineTran = trans?.Details?.FirstOrDefault(t => t.SrcValue == kpi.LineName);
                var titleTran = trans?.Details?.FirstOrDefault(t => t.SrcValue == kpi.Title);
                var proceTran = trans?.Details?.FirstOrDefault(t => t.SrcValue == kpi.ProcedureName);
                var dateTypeTran = trans?.Details?.FirstOrDefault(t => t.SrcValue == kpi.DateType);
                var m = kpiStatis.FirstOrDefault(expression.Compile());
                if (m == null)
                {
                    m = new t_kpi_statis()
                    {
                        org_id = kpi.OrgId,
                        date_type = kpi.DateType,
                        date_type_en = dateTypeTran?.TranValue,
                        line_name_en = lineTran?.TranValue,
                        title_en = titleTran?.TranValue,
                        procedure_name_en = proceTran?.TranValue,
                        target = kpi.Target,
                        target_pcs_qty = kpi.TargetPCSQty,
                        actual = kpi.Actual,
                        line_name = kpi.LineName,
                        line_code = kpi.LineCode,
                        title = kpi.Title,
                        curr_date = kpi.CurrDate,
                        checked_batch_ok_qty = kpi.CheckedBatchOkQty,
                        checked_batch_qty = kpi.CheckedBatchQty,
                        procedure_name = kpi.ProcedureName,
                        total_booking_qty = kpi.TotalBookingQty,
                        ok_qty = kpi.OkQty,
                        user_work_hour = kpi.UserWorkHour,
                        finish_statis_qty = kpi.FinishStatisQty,
                        type = kpi.Type,
                        time = kpi.Time
                    };
                    this.SetEntityId(m);
                    addList.Add(m);
                }
                else
                {
                    m.actual = kpi.Actual;
                    m.target = kpi.Target;
                    m.line_name = kpi.LineName;
                    m.line_code = kpi.LineCode;
                    m.date_type_en = dateTypeTran?.TranValue;
                    m.line_name_en = lineTran?.TranValue;
                    m.title_en = titleTran?.TranValue;
                    m.procedure_name_en = proceTran?.TranValue;
                    m.target_pcs_qty = kpi.TargetPCSQty;
                    m.checked_batch_ok_qty = kpi.CheckedBatchOkQty;
                    m.checked_batch_qty = kpi.CheckedBatchQty;
                    m.procedure_name = kpi.ProcedureName;
                    m.total_booking_qty = kpi.TotalBookingQty;
                    m.ok_qty = kpi.OkQty;
                    m.user_work_hour = kpi.UserWorkHour;
                    m.finish_statis_qty = kpi.FinishStatisQty;
                    m.type = kpi.Type;
                    m.time = kpi.Time;
                    updateList.Add(m);
                }
            }

            await this.statsDataRepository.CommitChangesByCommonAsync(() =>
            {
                this.statsDataRepository.CommonRepository.AddEntities(addList);
                this.statsDataRepository.CommonRepository.UpdateEntities(updateList);
            });

            return true;
        }

        public async Task<bool> SyncLineMotionAsync(List<SyncLineMotionModel> models)
        {
            if (models == null || !models.Any())
            {
                return true;
            }

            var addList = new List<t_line_motion>();
            var updateList = new List<t_line_motion>();
            var orgId = models.FirstOrDefault()?.OrgId;
            var apiParam = new ApiParam(orgId);
            var kpiStatis = await this.statsDataRepository.CommonRepository.GetEntitiesAsync<t_line_motion>(apiParam, t => t.org_id == orgId) ?? new List<t_line_motion>();

            foreach (var kpi in models)
            {
                var m = kpiStatis.FirstOrDefault(t => t.line_code == kpi.LineCode && t.org_id == kpi.OrgId && t.username == kpi.UserName && t.user_code == kpi.UserCode && t.code == kpi.Code && kpi.MotionDate == t.motion_date);
                if (m == null)
                {
                    m = new t_line_motion()
                    {
                        org_id = kpi.OrgId,
                        line_code = kpi.LineCode,
                        line_name = kpi.LineName,
                        user_code = kpi.UserCode,
                        username = kpi.UserName,
                        motioner_position = kpi.MotionerPosition,
                        motioner_level = kpi.MotionerLevel,
                        motioner_name = kpi.MotionerName,
                        motioner_location = kpi.MotionerLocation,
                        code = kpi.Code,
                        motion_date = kpi.MotionDate,
                        category = kpi.Category,
                        finish_date = kpi.FinishDate,
                        desc = kpi.Desc,
                        desc_image = kpi.DescImage,
                        improve_desc = kpi.ImproveDesc,
                        improve_desc_image = kpi.ImproveDescImage,
                        amount_saved = kpi.AmountSaved,
                        benefit = kpi.Benefit
                    };
                    this.SetEntityId(m);
                    addList.Add(m);
                }
                else
                {
                    m.motioner_position = kpi.MotionerPosition;
                    m.motioner_level = kpi.MotionerLevel;
                    m.motioner_name = kpi.MotionerName;
                    m.motioner_location = kpi.MotionerLocation;
                    m.code = kpi.Code;
                    m.motion_date = kpi.MotionDate;
                    m.category = kpi.Category;
                    m.finish_date = kpi.FinishDate;
                    m.desc = kpi.Desc;
                    m.desc_image = kpi.DescImage;
                    m.improve_desc = kpi.ImproveDesc;
                    m.improve_desc_image = kpi.ImproveDescImage;
                    m.amount_saved = kpi.AmountSaved;
                    m.benefit = kpi.Benefit;
                    updateList.Add(m);
                }
            }

            await this.statsDataRepository.CommitChangesByCommonAsync(() =>
            {
                this.statsDataRepository.CommonRepository.AddEntities(addList);
                this.statsDataRepository.CommonRepository.UpdateEntities(updateList);
            });

            return true;
        }

        /// <summary>
        /// 同步已经统计好的每道工序合格率数据，SQL统计只需要累计相乘
        /// </summary>
        /// <param name="models"></param>
        /// <returns></returns>
        public async Task<bool> SyncLineFpyBaseModelAsync(List<SyncLineFpyBaseModel> models)
        {
            if (models == null || !models.Any())
            {
                return true;
            }

            var addList = new List<t_line_fpy_base>();
            var updateList = new List<t_line_fpy_base>();
            var time = models.Min(t => t.CurrDate);
            var orgId = models.FirstOrDefault()?.OrgId;
            var apiParam = new ApiParam(orgId);
            var kpiStatis = await this.statsDataRepository.CommonRepository.GetEntitiesAsync<t_line_fpy_base>(apiParam, t => t.org_id == orgId && t.curr_date >= time) ?? new List<t_line_fpy_base>();
            var strs = new List<string>();
            strs.AddRange(models.Where(t => !string.IsNullOrEmpty(t.LineName)).Select(t => t.LineName).Distinct().ToList());
            strs.AddRange(models.Where(t => !string.IsNullOrEmpty(t.SectionDepartName)).Select(t => t.SectionDepartName).Distinct().ToList());
            var lineTrans = await this.RetryTranslateAsync(strs);
            foreach (var model in models)
            {
                Expression<Func<t_line_fpy_base, bool>> expression = t => t.line_code == model.LineCode && t.curr_date == model.CurrDate && t.procedure_code == model.ProcedureCode && t.org_id == model.OrgId;
                var m = kpiStatis.FirstOrDefault(expression.Compile());
                var tran = lineTrans?.Details?.FirstOrDefault(t => t.SrcValue == model.LineName);
                var shopTran = lineTrans?.Details?.FirstOrDefault(t => t.SrcValue == model.SectionDepartName);
                if (m == null)
                {
                    m = new t_line_fpy_base()
                    {
                        line_code = model.LineCode,
                        line_name = model.LineName,
                        line_name_en = tran?.TranValue,
                        section_depart_name_en = shopTran?.TranValue,
                        section_depart_id = model.SectionDepartId,
                        section_depart_name = model.SectionDepartName,
                        ok_qty = model.OkQty,
                        bad_qty = model.BadQty,
                        booking_total_qty = model.BookingTotalQty,
                        procedure_code = model.ProcedureCode,
                        procedure_name = model.ProcedureName,
                        curr_date = model.CurrDate,
                        org_id = model.OrgId
                    };
                    this.SetEntityId(m);
                    addList.Add(m);
                }
                else
                {
                    m.section_depart_id = model.SectionDepartId;
                    m.section_depart_name = model.SectionDepartName;
                    m.section_depart_name_en = shopTran?.TranValue;
                    m.ok_qty = model.OkQty;
                    m.bad_qty = model.BadQty;
                    m.line_name_en = tran?.TranValue;
                    m.booking_total_qty = model.BookingTotalQty;
                    m.procedure_code = model.ProcedureCode;
                    m.procedure_name = model.ProcedureName;
                    m.curr_date = model.CurrDate;
                    updateList.Add(m);
                }
            }

            await this.statsDataRepository.CommitChangesByCommonAsync(() =>
            {
                this.statsDataRepository.CommonRepository.AddEntities(addList);
                this.statsDataRepository.CommonRepository.UpdateEntities(updateList);
            });

            return true;
        }

        public async Task<bool> SyncManuSourceHourEfficiencyAsync(List<t_manu_source_hour_efficiency> entities)
        {
            if (entities == null || !entities.Any())
            {
                return false;
            }

            var addEntities = new List<t_manu_source_hour_efficiency>();
            var updateEntities = new List<t_manu_source_hour_efficiency>();
            var lineIds = entities.Select(t => t.line_id).Distinct().ToList();
            var startTime = entities.Min(t => t.curr_date);
            var endTime = entities.Max(t => t.curr_date);
            var orgId = entities.FirstOrDefault(t => !string.IsNullOrEmpty(t.org_id))?.org_id;  
            var existManuSourceHours = await this.statsDataRepository.GetManuSourceHourEfficiencyAsync(lineIds, orgId, startTime, endTime);
            foreach (var model in entities)
            {
                var entity = existManuSourceHours.FirstOrDefault(t => t.curr_date == model.curr_date && t.line_code == model.line_code && t.org_id == orgId && t.line_id == model.line_id);
                if (entity == null)
                {
                    entity = new t_manu_source_hour_efficiency()
                    {
                        line_id = model.line_id,
                        line_code = model.line_code,
                        line_name = model.line_name,
                        line_user_code = model.line_code,
                        line_user_name = model.line_user_name,
                        curr_date = model.curr_date,
                        actual_user_qty = model.actual_user_qty,
                        target_qty = model.target_qty,
                        total_in_qty = model.total_in_qty,
                        total_out_qty = model.total_out_qty,
                        store_qty = model.store_qty,
                        work_qty = model.work_qty,
                        total_in_standard_work_hour = model.total_in_standard_work_hour,
                        total_out_standard_work_hour = model.total_out_standard_work_hour,
                        manu_source_standard_work_hour = model.manu_source_standard_work_hour,
                        manu_source_working_hour = model.manu_source_working_hour,
                        fpy = model.fpy,
                        actual_capacity_rate = model.actual_capacity_rate,
                        labor_rate = model.labor_rate,
                        target_labor_rate = model.target_labor_rate,
                        manu_source_rate = model.manu_source_rate,
                        manu_source_target_rate = model.manu_source_target_rate,
                        total_rate = model.total_rate,
                        total_target_rate = model.total_target_rate,
                        org_id = model.org_id
                    };
                    this.SetEntityId(entity);
                    addEntities.Add(entity);
                }
                else
                {
                    entity.line_name = model.line_name;
                    entity.line_user_code = model.line_code;
                    entity.line_user_name = model.line_user_name;
                    entity.actual_user_qty = model.actual_user_qty;
                    entity.target_qty = model.target_qty;
                    entity.total_in_qty = model.total_in_qty;
                    entity.total_out_qty = model.total_out_qty;
                    entity.store_qty = model.store_qty;
                    entity.work_qty = model.work_qty;
                    entity.total_in_standard_work_hour = model.total_in_standard_work_hour;
                    entity.total_out_standard_work_hour = model.total_out_standard_work_hour;
                    entity.manu_source_standard_work_hour = model.manu_source_standard_work_hour;
                    entity.manu_source_working_hour = model.manu_source_working_hour;
                    entity.fpy = model.fpy;
                    entity.actual_capacity_rate = model.actual_capacity_rate;
                    entity.labor_rate = model.labor_rate;
                    entity.target_labor_rate = model.target_labor_rate;
                    entity.manu_source_rate = model.manu_source_rate;
                    entity.manu_source_target_rate = model.manu_source_target_rate;
                    entity.total_rate = model.total_rate;
                    entity.total_target_rate = model.total_target_rate;
                    entity.org_id = model.org_id;
                    updateEntities.Add(entity);
                }
            }

            return await this.statsDataRepository.AddOrUpdateManuSourceHourEfficiencyAsync(addEntities, updateEntities);
        }

        /// <summary>
        /// 同步月规划产能
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        public async Task<bool> SyncCapacityPlanAsync(List<SyncCapacityPlanModel> model)
        {
            List<t_wip_capacity_plan> addList = new List<t_wip_capacity_plan>();
            List<t_wip_capacity_plan> updateList = new List<t_wip_capacity_plan>();
            var orgId = model.FirstOrDefault()?.OrgId;
            var apiParam = new ApiParam(orgId);

            foreach (var m in model)
            {
                var obj = await statsDataRepository.CommonRepository.GetEntityAsync<t_wip_capacity_plan>(apiParam, t => t.time.Date == m.Time.Date && t.section_depart_id == m.SectionDepartId);
                if (obj == null)
                {
                    obj = new t_wip_capacity_plan()
                    {
                        org_id = m.OrgId,
                        time = m.Time,
                        section_depart_id = m.SectionDepartId,
                        wip_capacity_product_category_id = m.WipCapacityProductCategoryId,
                        work_day_num = m.WorkDayNum,
                        plan_qty = m.PlanQty,
                        plan_day_qty = m.PlanDayQty,
                        work_day_correct_num = m.WorkDayCorrectNum,
                        plan_correct_qty = m.PlanCorrectQty,
                        plan_day_correct_qty = m.PlanDayCorrectQty
                    };

                    SetEntityId(obj);
                    addList.Add(obj);
                }
                else
                {
                    obj.org_id = m.OrgId;
                    obj.time = m.Time;
                    obj.section_depart_id = m.SectionDepartId;
                    obj.wip_capacity_product_category_id = m.WipCapacityProductCategoryId;
                    obj.work_day_num = m.WorkDayNum;
                    obj.plan_qty = m.PlanQty;
                    obj.plan_day_qty = m.PlanDayQty;
                    obj.work_day_correct_num = m.WorkDayCorrectNum;
                    obj.plan_correct_qty = m.PlanCorrectQty;
                    obj.plan_day_correct_qty = m.PlanDayCorrectQty;
                    updateList.Add(obj);
                }
            }

            await statsDataRepository.CommitChangesByCommonAsync(() =>
            {
                statsDataRepository.CommonRepository.AddEntities(addList);
                statsDataRepository.CommonRepository.UpdateEntities(updateList);
            });

            return true;
        }
    }
}
